package com.jingdun.sport.api.security;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.jingdun.sport.api.config.ApiConfig;
import com.jingdun.sport.api.constants.CommonConstrants;
import com.jingdun.sport.api.helper.CommonsHelper;
import com.jingdun.sport.bean.app.param.RegisterMobile;
import com.jingdun.sport.bean.app.param.RegisterWeixin;
import com.jingdun.sport.bean.enums.SmsType;
import com.jingdun.sport.bean.model.LoginMobile;
import com.jingdun.sport.bean.model.User;
import com.jingdun.sport.common.constants.RedisConstants;
import com.jingdun.sport.common.util.RedisUtil;
import com.jingdun.sport.dao.LoginMobileMapper;
import com.jingdun.sport.security.enums.App;
import com.jingdun.sport.security.exception.WxErrorExceptionBase;
import com.jingdun.sport.security.provider.AbstractUserDetailsAuthenticationProvider;
import com.jingdun.sport.security.service.YamiUser;
import com.jingdun.sport.security.service.YamiUserDetailsService;
import com.jingdun.sport.service.UserAuthService;
import com.jingdun.sport.service.UserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Date;

/**
 * App登陆
 */
@Slf4j
@Component
@AllArgsConstructor
public class AppAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

    private final YamiUserDetailsService yamiUserDetailsService;

    @Autowired
    private UserAuthService userAuthService;

    @Autowired
    private UserService userService;

    @Autowired
    private LoginMobileMapper loginMobileMapper;

    @Autowired
    private ApiConfig apiConfig;

    @Override
    protected Authentication createSuccessAuthentication(Authentication authentication, UserDetails user) {
        AppAuthenticationToken result = new AppAuthenticationToken(user, authentication.getCredentials());
        result.setDetails(authentication.getDetails());
        result.setGrant_type(App.MOBILE.value());
        return result;
    }

    private YamiUser toYamiUser(User user) {
        YamiUser yamiUser = new YamiUser(user.getUserId(), "", App.MOBILE.value(), user.getStatus() == 1);
        BeanUtils.copyProperties(user, yamiUser);
        String name = StrUtil.isBlank(user.getRealName()) ? user.getNickName() : user.getRealName();
        yamiUser.setName(name);
        yamiUser.setPic(user.getPic());
        return yamiUser;
    }

    @Override
    protected UserDetails retrieveUser(String username, Authentication authentication) throws AuthenticationException {
        YamiUser loadedUser = null;
        AppAuthenticationToken token = (AppAuthenticationToken) authentication;
        switch (App.instance(token.getGrant_type())) {
//            手机登录
            case MOBILE:
                String code = RedisUtil.get(SmsType.REGISTER.value() + RedisConstants.PhoneCode + authentication.getPrincipal());
                if (code == null || !code.equals(authentication.getCredentials())) {
                    throw new WxErrorExceptionBase("验证码错误。");
                }
                loadedUser = yamiUserDetailsService.loadUserByMobile(authentication.getPrincipal().toString());
                if (loadedUser == null) {

                    //if (token.isRegisterIfNotExist()) {
                        RegisterMobile registerMobile = new RegisterMobile();
                        registerMobile.setMobile(authentication.getPrincipal().toString());
                        registerMobile.setMobileCode(authentication.getCredentials().toString());
                        loadedUser = toYamiUser(userAuthService.registerMobile(registerMobile));
                  //  }
                  /*  else {
                        throw new WxErrorExceptionBase("无此手机账号");
                    }
                   */
                }
                break;
//                微信登录
            case MP:
                loadedUser = yamiUserDetailsService.loadUserByOpenId(authentication.getPrincipal().toString());
                if (loadedUser == null) {
                    if (token.isRegisterIfNotExist()) {
                        RegisterWeixin registerWeixin = new RegisterWeixin();
                        registerWeixin.setNickname(token.getNickname());
                        registerWeixin.setHeadImg(token.getHeadImg());
                        registerWeixin.setSex(token.getSex());
                        registerWeixin.setProvince(token.getProvince());
                        registerWeixin.setCity(token.getCity());

                        registerWeixin.setOpenId(authentication.getPrincipal().toString());
                        registerWeixin.setUnionId(token.getUnionId());
                        loadedUser = toYamiUser(userAuthService.registerWeixin(registerWeixin));
                    }
                    else {
                        throw new WxErrorExceptionBase("无此微信账号");
                    }
                }
                break;
//                小程序
            case MINI:
                break;
            default:
                break;
        }
        User user = new User();
        Date nowDate = new Date();
        String ip = CommonsHelper.getCliectIp(((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
        user.setUserLastip(ip);
        user.setUserLasttime(nowDate);
        user.setUserId(loadedUser.getUserId());
        userService.updateById(user);
        return loadedUser;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return AppAuthenticationToken.class.isAssignableFrom(authentication);
    }


    @Override
    protected App getAppInfo() {
        return App.MOBILE;
    }
}
